<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" >
<link href="cmd.css" rel="stylesheet" type="text/css">
<title>GRUB4DOS 扇区序列</title>
</head>

<body>
<h1>扇区序列文件的长度指定，精确到字节（未公开特性）<br />
</h1>
<p>摘自：<a target=_blank href="http://bbs.znpc.net/viewthread.php?tid=4532">http://bbs.znpc.net/viewthread.php?tid=4532</a></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a target=_blank href="http://chenall.net/post/post41/">http://chenall.net/post/post41/</a></p>
<p class="style1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在 grub 中，我们可以用 (hd0)12345+8 或者 (hd0,0)2+20,33+5,87+300 之类的表达法来表示一个磁盘文件。这种表示法，就是扇区序列表示法。既然是扇区序列，那么这样的文件，就只能以扇区对齐（也即必须为 512 的整数倍），也就是说，不可能表示一个 256 字节的文件，也不可能表示一个 513 字节的文件。<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;对于内存文件来讲，也是如此，(md)xxxxx+yyyyy 和 (rd)xxxxx+yyyyy 这类表达法都是表示扇区的整数倍，这样大小的文件。然而有时候，我们确实需要精确到字节的扇区序列文件。比如在硬盘上（或内存中）有一个image.gz 文件，如果你不指定这个文件的精确大小，那么grub 就不能正常解压这个文件，这是因为解压程序依赖于这个 gz 的精确长度，你多一个字节或少一个字节，都可能会失败的。<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;怎样指定扇区序列的精确长度呢？这可能是 GNU GRUB 早期的开发者早就开发的功能了，只是没有公开，也许是因为开发者觉得这个功能的实现方法以后说不定会改变，就不适合公开了。扇区序列的精确长度（以字节计），是直接加在扇区序列表达法之后的，用逗号与扇区序列隔开。<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;例如，你想打印出 MBR 中开头的 466 个字节，就可以这样：<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cat --hex (hd0)+1,466<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;其中 (hd0)+1 是扇区序列，466 表示只从扇区序列中取出 466 字节作为文件的长度。<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;再举一例：<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cat --hex (hd0)+63,800+63,64400<br>
&nbsp;&nbsp;&nbsp;&nbsp;  &nbsp;&nbsp;&nbsp;&nbsp;如果没有结尾的&ldquo;,64400&rdquo;，那么，&ldquo;(hd0)+63,800+63&rdquo;就表示不连续的两个扇区序列所组成的文件，每个连续的序列都有 63 个扇区，所以文件总共有 126 个扇区。文件的长度就是 126&times;512=64512 字节。加上了结尾的&ldquo;,64400&rdquo;之后，文件变小了，它表示的文件长度为 64400。当然你不应该指定一个长度，使得它比扇区序列的总长度还要大。<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;但是，如果你想**只**访问 MBR 中的分区表，那是不行的，这种表达法不支持从扇区序列的中间截取文件，只支持从扇区序列的最开头截取一定长度的文件。<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;由于这种表达法也是有缺点的，因此我们也仍然不公开这一特性。今后说不定会出现一种更合理的表达方式。</p>
<p class="style1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;以下引用内容同上，<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  (rd)+1 是经过特殊处理的。它永远代表 (rd) 设备的全部内容。因此，你可能无法只获取它的第一个扇区。但是你可以获取它的两个扇区：(rd)+2 这个是可以的。<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;你也可以这样： (rd)+1,511 这个文件比 512 字节少了一个字节，所以，它不再代表整个 (rd) 设备的内容。<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;或者可以这样： (rd)+2,513 这个文件的长度是 513，所以，它也不代表整个 (rd) 设备的内容。<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(rd) 设备的长度是精确到字节的。用 map --status 可以显示 rd 的长度。</p>
</body>
</html>
